package felix.dataviewer.Model;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import felix.dataviewer.App;
import felix.dataviewer.Data.AppBean;
import felix.dataviewer.Data.DBBean;
import io.reactivex.Observable;
import io.reactivex.Single;

/**
 * Created by huangmf on 7/28/2017.
 */

public class AppModel {
    private final static String TAG = AppModel.class.getSimpleName();
    private static WeakReference<PackageManager> sPm;

    public static Single<List<AppBean>> getAppBean() {
        return Observable
                .create(e -> {
                    e.onNext(getInfos());
                    e.onComplete();
                })
                .map(o -> ((List<ResolveInfo>) o))
                .flatMap(rInfos -> Observable.fromIterable(rInfos))
                .map(rInfo -> rInfo.activityInfo)
                .map(atyInfo -> toAppBean(atyInfo))
                .toList();
    }

    /**
     * 将应用信息转为App信息
     *
     * @param atyInfo
     * @return
     */
    private static AppBean toAppBean(ActivityInfo atyInfo) {
        AppBean appBean = new AppBean();

        List<DBBean> dbBeen = new ArrayList<>();
        File data = new File(Environment.getDataDirectory(), "data");
        File appDir = new File(data, atyInfo.packageName);
        File dbDir = new File(appDir, "database");
        if (!dbDir.canRead()) {
            String error = dbDir.getAbsolutePath() + " can't be read.";
            final IllegalAccessException e;
            e = new IllegalAccessException(error);
            Log.w(TAG, "toAppBean: " + error, e);
            return null;
        }
        File[] dbFiles = dbDir.listFiles();
        if (dbFiles == null || dbFiles.length <= 0) {
            final String path = dbDir.getAbsolutePath();
            final String error = path + "　has not files.";
            Log.w(TAG, "toAppBean: " + error);
            return null;
        }
        for (File dbFile : dbFiles) {
            DBBean dbBean = new DBBean();
            dbBean.setName(dbFile.getName());
            dbBeen.add(dbBean);
        }
        appBean.setPkgName(atyInfo.packageName);
        appBean.setLabel(atyInfo.loadLabel(getPm()));
        appBean.setIcon(atyInfo.loadIcon(getPm()));
        appBean.setLauncherAty(atyInfo.name);
        final int SYS_FLAG = ApplicationInfo.FLAG_SYSTEM;
        final int flags = atyInfo.applicationInfo.flags;
        appBean.setSystem((flags & SYS_FLAG) != 0);
        appBean.setChildren(dbBeen);
        return appBean;
    }

    /**
     * 获取安装的应用信息
     *
     * @return
     */
    private static List<ResolveInfo> getInfos() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        final int flag = PackageManager.MATCH_ALL;
        final PackageManager pm = AppModel.getPm();
        return pm.queryIntentActivities(intent, flag);
    }

    /**
     * 获取PackageManager管理器
     *
     * @return
     */
    private static PackageManager getPm() {
        if (sPm == null || sPm.get() == null) {
            final Context ctx = App.getContext();
            final PackageManager pm = ctx.getPackageManager();
            sPm = new WeakReference<>(pm);
        }
        return sPm.get();
    }
}
